//
//  TableViewDelegateSource.m
//  MutipleTableView
//
//  Created by admin on 2022/1/21.
//

#import "TableViewDelegateSource.h"

@interface TableViewDelegateSource ()
{
    NSInteger (^kyg_numberOfRowsInSection)(UITableView * tableView, NSInteger section);
    UITableViewCell* (^kyg_cellForRowAtIndexPath)(UITableView * tableView, NSIndexPath* indexPath);


    NSInteger (^kyg_numberOfSectionsInTableView)(UITableView * tableView);
    NSString * (^kyg_titleForHeaderInSection)(UITableView * tableView, NSInteger section);
    NSString * (^kyg_titleForFooterInSection)(UITableView * tableView, NSInteger section);
    BOOL (^kyg_canEditRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);
    BOOL (^kyg_canMoveRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);

    NSArray<NSString *> * (^kyg_sectionIndexTitlesForTableView)(UITableView * tableView);

    NSInteger (^kyg_sectionForSectionIndexTitle)(UITableView * tableView, NSString *title,NSInteger index);

    NSInteger (^kyg_commitEditingStyle)(UITableView * tableView, UITableViewCellEditingStyle editingStyle,NSIndexPath * indexPath);
    NSInteger (^kyg_moveRowAtIndexPath)(UITableView * tableView, NSIndexPath * sourceIndexPath,NSIndexPath * destinationIndexPath);

    #pragma mark - delegate - 常用delegate
    // Display customization
    void (^kyg_willDisplayCell)(UITableView * tableView, UITableViewCell * cell, NSIndexPath * indexPath);
    void (^kyg_willDisplayHeaderView)(UITableView * tableView, UIView *view, NSInteger section);
    void (^kyg_willDisplayFooterView)(UITableView * tableView, UIView * view, NSInteger section);
    void (^kyg_didEndDisplayingCell)(UITableView * tableView, UITableViewCell * cell, NSIndexPath * indexPath);
    void (^kyg_didEndDisplayingHeaderView)(UITableView * tableView, UIView * view, NSInteger section);
    void (^kyg_didEndDisplayingFooterView)(UITableView * tableView, UIView * view, NSInteger section);

    // Variable height support
    CGFloat (^kyg_heightForRowAtIndexPath)(UITableView * tableView, NSIndexPath* indexPath);
    CGFloat (^kyg_heightForHeaderInSection)(UITableView * tableView, NSInteger section);
    CGFloat (^kyg_heightForFooterInSection)(UITableView * tableView, NSInteger section);
    // Use the estimatedHeight methods to quickly calculate guessed values which will allow for fast load times of the table.
    // If these methods are implemented, the above -tableView:heightForXXX calls will be deferred until views are ready to be displayed, so more expensive logic can be placed there.
    CGFloat (^kyg_estimatedHeightForRowAtIndexPath)(UITableView * tableView, NSIndexPath* indexPath);
    CGFloat (^kyg_estimatedHeightForHeaderInSection)(UITableView* tableView, NSInteger section);
    CGFloat (^kyg_estimatedHeightForFooterInSection)(UITableView * tableView, NSInteger section);


    // Section header & footer information. Views are preferred over title should you decide to provide both
    UIView* (^kyg_viewForHeaderInSection)(UITableView * tableView, NSInteger section);
    UIView* (^kyg_viewForFooterInSection)(UITableView * tableView, NSInteger section);

    // Accessories (disclosures).
    void (^kyg_accessoryButtonTappedForRowWithIndexPath)(UITableView * tableView, NSIndexPath * indexPath);
    // Selection

    // -tableView:shouldHighlightRowAtIndexPath: is called when a touch comes down on a row.
    // Returning NO to that message halts the selection process and does not cause the currently selected row to lose its selected look while the touch is down.
    BOOL (^kyg_shouldHighlightRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);
    void (^kyg_didHighlightRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);
    void (^kyg_didUnhighlightRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);

    // Called before the user changes the selection. Return a new indexPath, or nil, to change the proposed selection.
    NSIndexPath * (^kyg_willSelectRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);
    NSIndexPath * (^kyg_willDeselectRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);
    // Called after the user changes the selection.
    void (^kyg_didSelectRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);
    void (^kyg_didDeselectRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);
    // Editing

    // Allows customization of the editingStyle for a particular cell located at 'indexPath'. If not implemented, all editable cells will have UITableViewCellEditingStyleDelete set for them when the table has editing property set to YES.
    UITableViewCellEditingStyle (^kyg_editingStyleForRowAtIndexPath)(UITableView * tableView,NSIndexPath * indexPath);

    NSString * (^kyg_titleForDeleteConfirmationButtonForRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);

    // Swipe actions
    // These methods supersede -editActionsForRowAtIndexPath: if implemented
    // return nil to get the default swipe actions
    UISwipeActionsConfiguration* (^kyg_leadingSwipeActionsConfigurationForRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath) API_AVAILABLE(ios(11.0));
    UISwipeActionsConfiguration* (^kyg_trailingSwipeActionsConfigurationForRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath) API_AVAILABLE(ios(11.0));

    // Controls whether the background is indented while editing.  If not implemented, the default is YES.  This is unrelated to the indentation level below.  This method only applies to grouped style table views.
    BOOL (^kyg_shouldIndentWhileEditingRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);
    // The willBegin/didEnd methods are called whenever the 'editing' property is automatically changed by the table (allowing insert/delete/move). This is done by a swipe activating a single row
    NSInteger (^kyg_willBeginEditingRowAtIndexPath)(UITableView * tableView,NSIndexPath * indexPath);
    void (^kyg_didEndEditingRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);

    // Moving/reordering

    // Allows customization of the target row for a particular row as it is being moved/reordered
    NSIndexPath * (^kyg_targetIndexPathForMoveFromRowAtIndexPath)(UITableView * tableView, NSIndexPath * sourceIndexPath, NSIndexPath * proposedDestinationIndexPath);
    // Indentation
    NSInteger (^kyg_indentationLevelForRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);

    // Copy/Paste.  All three methods must be implemented by the delegate.
    //- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath API_DEPRECATED_WITH_REPLACEMENT("tableView:contextMenuConfigurationForRowAtIndexPath:point:", ios(5.0, 13.0));
    //..
    // Focus
    BOOL (^kyg_canFocusRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath) API_AVAILABLE(ios(9.0));
    BOOL (^kyg_shouldUpdateFocusInContext)(UITableView * tableView, UITableViewFocusUpdateContext* context) API_AVAILABLE(ios(9.0));

    void (^kyg_didUpdateFocusInContext)(UITableView * tableView, UITableViewFocusUpdateContext * context, UIFocusAnimationCoordinator * coordinator) API_AVAILABLE(ios(9.0));
    NSIndexPath * (^kyg_indexPathForPreferredFocusedViewInTableView)(UITableView * tableView) API_AVAILABLE(ios(9.0));

    /// Determines if the row at the specified index path should also become selected when focus moves to it.
    /// If the table view's global selectionFollowsFocus is enabled, this method will allow you to override that behavior on a per-index path basis. This method is not called if selectionFollowsFocus is disabled.
    BOOL (^kyg_selectionFollowsFocusForRowAtIndexPath)(UITableView * tableView, NSIndexPath * indexPath);
}
@end
@implementation TableViewDelegateSource

- (instancetype)initWithTableView:(UITableView *)tableView
{
    self = [super init];
    if (self) {
        tableView.delegate = self;
        tableView.dataSource = self;
    }
    return self;
}

- (TableViewDelegateSource *(^)(NSInteger (^)(UITableView *, NSInteger)))numberOfRowsInSection {
    return ^TableViewDelegateSource *(NSInteger (^block)(UITableView *, NSInteger)) {
        self->kyg_numberOfRowsInSection = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(UITableViewCell * _Nonnull (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))cellForRowAtIndexPath {
    return ^TableViewDelegateSource *(UITableViewCell *(^block)(UITableView *, NSIndexPath *)) {
        self->kyg_cellForRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource *(^)(NSInteger (^)(UITableView *)))numberOfSectionsInTableView {
    return ^TableViewDelegateSource *(NSInteger (^block)(UITableView *)) {
        self->kyg_numberOfSectionsInTableView = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(NSString * _Nonnull (^ _Nonnull)(UITableView * _Nonnull, NSInteger)))titleForHeaderInSection {
    return ^TableViewDelegateSource *(NSString* (^block)(UITableView *,NSInteger)) {
        self->kyg_titleForHeaderInSection = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(NSString * _Nonnull (^ _Nonnull)(UITableView * _Nonnull, NSInteger)))titleForFooterInSection {
    return ^TableViewDelegateSource *(NSString* (^block)(UITableView *,NSInteger)) {
        self->kyg_titleForFooterInSection = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(BOOL (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))canEditRowAtIndexPath {
    return ^TableViewDelegateSource*(BOOL (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_canEditRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(BOOL (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))canMoveRowAtIndexPath {
    return ^TableViewDelegateSource*(BOOL (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_canMoveRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(NSArray<NSString *> * _Nonnull (^ _Nonnull)(UITableView * _Nonnull)))sectionIndexTitlesForTableView {
    return ^TableViewDelegateSource*(NSArray<NSString *> * (^ block)(UITableView * _Nonnull)){
        self->kyg_sectionIndexTitlesForTableView = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(NSInteger (^ _Nonnull)(UITableView * _Nonnull, NSString * _Nonnull, NSInteger)))sectionForSectionIndexTitle {
    return ^TableViewDelegateSource*(NSInteger (^ block)(UITableView * _Nonnull, NSString * _Nonnull, NSInteger)){
        self->kyg_sectionForSectionIndexTitle = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(NSInteger (^ _Nonnull)(UITableView * _Nonnull, UITableViewCellEditingStyle, NSIndexPath * _Nonnull)))commitEditingStyle {
    return ^TableViewDelegateSource*(NSInteger (^ block)(UITableView * _Nonnull, UITableViewCellEditingStyle, NSIndexPath * _Nonnull)){
        self->kyg_commitEditingStyle = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(NSInteger (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull, NSIndexPath * _Nonnull)))moveRowAtIndexPath {
    return ^TableViewDelegateSource*(NSInteger (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_moveRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, UITableViewCell * _Nonnull, NSIndexPath * _Nonnull)))willDisplayCell {
    return ^TableViewDelegateSource*(void (^ block)(UITableView * _Nonnull, UITableViewCell * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_willDisplayCell = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, UIView * _Nonnull, NSInteger)))willDisplayHeaderView {
    return ^TableViewDelegateSource*(void (^ block)(UITableView * _Nonnull, UIView * _Nonnull, NSInteger)){
        self->kyg_willDisplayHeaderView = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, UIView * _Nonnull, NSInteger)))willDisplayFooterView {
    return ^TableViewDelegateSource*(void (^ block)(UITableView * _Nonnull, UIView * _Nonnull, NSInteger)){
        self->kyg_willDisplayFooterView = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, UITableViewCell * _Nonnull, NSIndexPath * _Nonnull)))didEndDisplayingCell{
    return ^TableViewDelegateSource*(void (^ block)(UITableView * _Nonnull, UITableViewCell * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_didEndDisplayingCell = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, UIView * _Nonnull, NSInteger)))didEndDisplayingHeaderView {
    return ^TableViewDelegateSource*(void (^ block)(UITableView * _Nonnull, UIView * _Nonnull, NSInteger)){
        self->kyg_didEndDisplayingHeaderView = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, UIView * _Nonnull, NSInteger)))didEndDisplayingFooterView
{
    return ^TableViewDelegateSource*(void (^ block)(UITableView * _Nonnull, UIView * _Nonnull, NSInteger)){
        self->kyg_didEndDisplayingFooterView = block;
        return self;
    };
}
//
- (TableViewDelegateSource * _Nonnull (^)(CGFloat (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))heightForRowAtIndexPath{
    return ^TableViewDelegateSource *(CGFloat (^block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)) {
        self->kyg_heightForRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource *(^)(CGFloat (^)(UITableView *, NSInteger)))heightForHeaderInSection{
    return ^TableViewDelegateSource *(CGFloat (^block)(UITableView *, NSInteger)) {
        self->kyg_heightForHeaderInSection = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(CGFloat (^ _Nonnull)(UITableView * _Nonnull, NSInteger)))heightForFooterInSection {
    return ^TableViewDelegateSource *(CGFloat (^block)(UITableView *, NSInteger)) {
        self->kyg_heightForFooterInSection = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(CGFloat (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))estimatedHeightForRowAtIndexPath {
    return ^TableViewDelegateSource *(CGFloat (^block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)) {
        self->kyg_estimatedHeightForRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(CGFloat (^ _Nonnull)(UITableView * _Nonnull, NSInteger)))estimatedHeightForHeaderInSection{
    return ^TableViewDelegateSource *(CGFloat (^block)(UITableView *, NSInteger)) {
        self->kyg_estimatedHeightForHeaderInSection = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(CGFloat (^ _Nonnull)(UITableView * _Nonnull, NSInteger)))estimatedHeightForFooterInSection {
    return ^TableViewDelegateSource *(CGFloat (^block)(UITableView *, NSInteger)) {
        self->kyg_estimatedHeightForFooterInSection = block;
        return self;
    };
}
//
- (TableViewDelegateSource * _Nonnull (^)(UIView * _Nonnull (^ _Nonnull)(UITableView * _Nonnull, NSInteger)))viewForHeaderInSection {
    return ^TableViewDelegateSource *(UIView* (^block)(UITableView *, NSInteger)) {
        self->kyg_viewForHeaderInSection = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(UIView * _Nonnull (^ _Nonnull)(UITableView * _Nonnull, NSInteger)))viewForFooterInSection{
    return ^TableViewDelegateSource *(UIView* (^block)(UITableView *, NSInteger)) {
        self->kyg_viewForFooterInSection = block;
        return self;
    };
}
//
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))accessoryButtonTappedForRowWithIndexPath{
    return ^TableViewDelegateSource *(void (^block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)) {
        self->kyg_accessoryButtonTappedForRowWithIndexPath = block;
        return self;
    };
}
//
- (TableViewDelegateSource * _Nonnull (^)(BOOL (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))shouldHighlightRowAtIndexPath {
    return ^TableViewDelegateSource *(BOOL (^block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)) {
        self->kyg_shouldHighlightRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))didHighlightRowAtIndexPath{
    return ^TableViewDelegateSource *(void (^block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)) {
        self->kyg_didHighlightRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))didUnhighlightRowAtIndexPath{
    return ^TableViewDelegateSource *(void (^block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)) {
        self->kyg_didUnhighlightRowAtIndexPath = block;
        return self;
    };
}
//
- (TableViewDelegateSource * _Nonnull (^)(NSIndexPath * _Nonnull (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))willSelectRowAtIndexPath {
    return ^TableViewDelegateSource *(NSIndexPath * _Nonnull(^block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)) {
        self->kyg_willSelectRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(NSIndexPath * _Nonnull (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))willDeselectRowAtIndexPath{
    return ^TableViewDelegateSource *(NSIndexPath * _Nonnull(^block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)) {
        self->kyg_willDeselectRowAtIndexPath = block;
        return self;
    };
}
//
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))didSelectRowAtIndexPath {
    return ^TableViewDelegateSource*(void (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_didSelectRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))didDeselectRowAtIndexPath {
    return ^TableViewDelegateSource*(void (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_didDeselectRowAtIndexPath = block;
        return self;
    };
}
//
- (TableViewDelegateSource * _Nonnull (^)(UITableViewCellEditingStyle (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))editingStyleForRowAtIndexPath {
    return ^TableViewDelegateSource*(UITableViewCellEditingStyle (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_editingStyleForRowAtIndexPath = block;
        return self;
    };
}
//
- (TableViewDelegateSource * _Nonnull (^)(NSString * _Nonnull (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))titleForDeleteConfirmationButtonForRowAtIndexPath {
    return ^TableViewDelegateSource*(NSString * _Nonnull  (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_titleForDeleteConfirmationButtonForRowAtIndexPath = block;
        return self;
    };
}
//
- (TableViewDelegateSource * _Nonnull (^)(UISwipeActionsConfiguration * _Nonnull (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))leadingSwipeActionsConfigurationForRowAtIndexPath {
    return ^TableViewDelegateSource*(UISwipeActionsConfiguration * _Nonnull  (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_leadingSwipeActionsConfigurationForRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(UISwipeActionsConfiguration * _Nonnull (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))trailingSwipeActionsConfigurationForRowAtIndexPath{
    return ^TableViewDelegateSource*(UISwipeActionsConfiguration * _Nonnull  (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_trailingSwipeActionsConfigurationForRowAtIndexPath = block;
        return self;
    };
}
//
- (TableViewDelegateSource * _Nonnull (^)(BOOL (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))shouldIndentWhileEditingRowAtIndexPath {
    return ^TableViewDelegateSource*(BOOL (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_shouldIndentWhileEditingRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(NSInteger (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))willBeginEditingRowAtIndexPath {
    return ^TableViewDelegateSource*(NSInteger (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_willBeginEditingRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))didEndEditingRowAtIndexPath{
    return ^TableViewDelegateSource*(void (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_didEndEditingRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(NSIndexPath * _Nonnull (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull, NSIndexPath * _Nonnull)))targetIndexPathForMoveFromRowAtIndexPath {
    return ^TableViewDelegateSource*(NSIndexPath * (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_targetIndexPathForMoveFromRowAtIndexPath = block;
        return self;
    };
}
   
- (TableViewDelegateSource * _Nonnull (^)(NSInteger (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))indentationLevelForRowAtIndexPath {
    return ^TableViewDelegateSource*(NSInteger (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_indentationLevelForRowAtIndexPath = block;
        return self;
    };
}
//
//
- (TableViewDelegateSource * _Nonnull (^)(BOOL (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))canFocusRowAtIndexPath {
    return ^TableViewDelegateSource*(BOOL (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_canFocusRowAtIndexPath = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(BOOL (^ _Nonnull)(UITableView * _Nonnull, UITableViewFocusUpdateContext * _Nonnull)))shouldUpdateFocusInContext {
    return ^TableViewDelegateSource*(BOOL (^ block)(UITableView * _Nonnull, UITableViewFocusUpdateContext * _Nonnull)){
        self->kyg_shouldUpdateFocusInContext = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(void (^ _Nonnull)(UITableView * _Nonnull, UITableViewFocusUpdateContext * _Nonnull, UIFocusAnimationCoordinator * _Nonnull)))didUpdateFocusInContext{
    return ^TableViewDelegateSource*(void (^ block)(UITableView * _Nonnull, UITableViewFocusUpdateContext * _Nonnull, UIFocusAnimationCoordinator * _Nonnull)){
        self->kyg_didUpdateFocusInContext = block;
        return self;
    };
}

- (TableViewDelegateSource * _Nonnull (^)(NSIndexPath * _Nonnull (^ _Nonnull)(UITableView * _Nonnull)))indexPathForPreferredFocusedViewInTableView{
    return ^TableViewDelegateSource*(NSIndexPath * (^ block)(UITableView * _Nonnull)){
        self->kyg_indexPathForPreferredFocusedViewInTableView = block;
        return self;
    };
}
- (TableViewDelegateSource * _Nonnull (^)(BOOL (^ _Nonnull)(UITableView * _Nonnull, NSIndexPath * _Nonnull)))selectionFollowsFocusForRowAtIndexPath
{
    return ^TableViewDelegateSource*(BOOL (^ block)(UITableView * _Nonnull, NSIndexPath * _Nonnull)){
        self->kyg_selectionFollowsFocusForRowAtIndexPath = block;
        return self;
    };
}




#pragma mark - Table view datasource methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    if (kyg_numberOfRowsInSection) {
        return kyg_numberOfRowsInSection(tableView, section);
    }
    return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (kyg_cellForRowAtIndexPath) {
        return kyg_cellForRowAtIndexPath(tableView, indexPath);
    }
    return [UITableViewCell new];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    
    if (kyg_numberOfSectionsInTableView) {
        return kyg_numberOfSectionsInTableView(tableView);
    }
    return 1;
}

- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
    if (kyg_titleForHeaderInSection) {
        return kyg_titleForHeaderInSection(tableView, section);
    }
    return nil;
}
- (nullable NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
    if (kyg_titleForFooterInSection) {
        return kyg_titleForFooterInSection(tableView, section);
    }
    return nil;
}

// Editing

// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
    if (kyg_canEditRowAtIndexPath) {
        return kyg_canEditRowAtIndexPath(tableView, indexPath);
    }
    return false;
}

// Moving/reordering

// Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath{
    if (kyg_canMoveRowAtIndexPath) {
        return kyg_canMoveRowAtIndexPath(tableView, indexPath);
    }
    return false;
}

// Index

- (nullable NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView;{
    if (kyg_sectionIndexTitlesForTableView) {
        return kyg_sectionIndexTitlesForTableView(tableView);
    }
    return @[];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{
    
    if (kyg_sectionForSectionIndexTitle) {
        return kyg_sectionForSectionIndexTitle(tableView, title, index);
    }
    return 1;
}

// Data manipulation - insert and delete support

// After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change
// Not called for edit actions using UITableViewRowAction - the action's handler will be invoked instead
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    if (kyg_commitEditingStyle) {
        kyg_commitEditingStyle(tableView, editingStyle, indexPath);
    }
}

// Data manipulation - reorder / moving support

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
    if (kyg_moveRowAtIndexPath) {
        kyg_moveRowAtIndexPath(tableView, sourceIndexPath, destinationIndexPath);
    }
}


#pragma mark - Table view delegate methods

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (kyg_willDisplayCell) kyg_willDisplayCell(tableView, cell, indexPath);
}
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section API_AVAILABLE(ios(6.0)) {
    if (kyg_willDisplayHeaderView) kyg_willDisplayHeaderView(tableView, view, section);
}
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section API_AVAILABLE(ios(6.0)) {
    if (kyg_willDisplayFooterView) kyg_willDisplayFooterView(tableView, view, section);
}
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath API_AVAILABLE(ios(6.0)) {
    if (kyg_didEndDisplayingCell) kyg_didEndDisplayingCell(tableView, cell, indexPath);
}
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section API_AVAILABLE(ios(6.0)) {
    if (kyg_didEndDisplayingHeaderView) kyg_didEndDisplayingHeaderView(tableView, view, section);
}
- (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section API_AVAILABLE(ios(6.0)) {
    if (kyg_didEndDisplayingFooterView) kyg_didEndDisplayingFooterView(tableView, view, section);
}

// Variable height support

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    if (kyg_heightForRowAtIndexPath) {
        return kyg_heightForRowAtIndexPath(tableView, indexPath);
    }
    return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    
    if (kyg_heightForHeaderInSection) {
        return kyg_heightForHeaderInSection(tableView,section);
    }
    return CGFLOAT_MIN;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
    
    if (kyg_heightForFooterInSection) {
        return kyg_heightForFooterInSection(tableView,section);
    }
    return CGFLOAT_MIN;
}

// Use the estimatedHeight methods to quickly calculate guessed values which will allow for fast load times of the table.
// If these methods are implemented, the above -tableView:heightForXXX calls will be deferred until views are ready to be displayed, so more expensive logic can be placed there.
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(7.0)){
    
    if (kyg_estimatedHeightForRowAtIndexPath) {
        return kyg_estimatedHeightForRowAtIndexPath(tableView, indexPath);
    }
    return 44;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section API_AVAILABLE(ios(7.0)){
    
    if (kyg_estimatedHeightForHeaderInSection) {
        return kyg_estimatedHeightForHeaderInSection(tableView,section);
    }
    return 44;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section API_AVAILABLE(ios(7.0)){
    
    if (kyg_estimatedHeightForFooterInSection) {
        return kyg_estimatedHeightForFooterInSection(tableView,section);
    }
    return 44;
}

// Section header & footer information. Views are preferred over title should you decide to provide both

- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    if (kyg_viewForHeaderInSection) {
        return kyg_viewForHeaderInSection(tableView, section);
    }
    return [UIView new];
}
- (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
    if (kyg_viewForFooterInSection) {
        return kyg_viewForFooterInSection(tableView, section);
    }
    return [UIView new];
}

// Accessories (disclosures).

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
    if (kyg_accessoryButtonTappedForRowWithIndexPath) {
        kyg_accessoryButtonTappedForRowWithIndexPath(tableView, indexPath);
    }
}

// Selection

// -tableView:shouldHighlightRowAtIndexPath: is called when a touch comes down on a row.
// Returning NO to that message halts the selection process and does not cause the currently selected row to lose its selected look while the touch is down.
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(6.0)){
    if (kyg_shouldHighlightRowAtIndexPath) {
        return kyg_shouldHighlightRowAtIndexPath(tableView, indexPath);
    }
    return TRUE;
}
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(6.0)) {
    if (kyg_didHighlightRowAtIndexPath) {
        return kyg_didHighlightRowAtIndexPath(tableView, indexPath);
    }
}
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(6.0)) {
    if (kyg_didUnhighlightRowAtIndexPath) {
        return kyg_didUnhighlightRowAtIndexPath(tableView, indexPath);
    }
}

// Called before the user changes the selection. Return a new indexPath, or nil, to change the proposed selection.
- (nullable NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    if (kyg_willSelectRowAtIndexPath) {
        return kyg_willSelectRowAtIndexPath(tableView, indexPath);
    }
    return indexPath;
}
- (nullable NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(3.0)){
    if (kyg_willDeselectRowAtIndexPath) {
        return kyg_willDeselectRowAtIndexPath(tableView, indexPath);
    }
    return indexPath;
}
// Called after the user changes the selection.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (kyg_didSelectRowAtIndexPath) {
        kyg_didSelectRowAtIndexPath(tableView, indexPath);
    }
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(3.0)){
    if (kyg_didDeselectRowAtIndexPath) {
        kyg_didDeselectRowAtIndexPath(tableView, indexPath);
    }
}

// Editing

// Allows customization of the editingStyle for a particular cell located at 'indexPath'. If not implemented, all editable cells will have UITableViewCellEditingStyleDelete set for them when the table has editing property set to YES.
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
    if (kyg_editingStyleForRowAtIndexPath) {
        return kyg_editingStyleForRowAtIndexPath(tableView,indexPath);
    }
    if (tableView.editing) {
        return UITableViewCellEditingStyleDelete;
    } else {
        return UITableViewCellEditingStyleNone;
    }
}
- (nullable NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(3.0)) API_UNAVAILABLE(tvos){
    if (kyg_titleForDeleteConfirmationButtonForRowAtIndexPath) {
        return kyg_titleForDeleteConfirmationButtonForRowAtIndexPath(tableView, indexPath);
    }
    return nil;
}

// This method supersedes -tableView:titleForDeleteConfirmationButtonForRowAtIndexPath: if return value is non-nil
//- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath API_DEPRECATED_WITH_REPLACEMENT("tableView:trailingSwipeActionsConfigurationForRowAtIndexPath:", ios(8.0, 13.0)) API_UNAVAILABLE(tvos);

// Swipe actions
// These methods supersede -editActionsForRowAtIndexPath: if implemented
// return nil to get the default swipe actions
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos){
    if (kyg_leadingSwipeActionsConfigurationForRowAtIndexPath) {
        return kyg_leadingSwipeActionsConfigurationForRowAtIndexPath(tableView, indexPath);
    }
    return nil;
}
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos){
    if (kyg_trailingSwipeActionsConfigurationForRowAtIndexPath) {
        return kyg_trailingSwipeActionsConfigurationForRowAtIndexPath(tableView, indexPath);
    }
    return nil;
}

// Controls whether the background is indented while editing.  If not implemented, the default is YES.  This is unrelated to the indentation level below.  This method only applies to grouped style table views.
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath{
    
    if (kyg_shouldIndentWhileEditingRowAtIndexPath) {
        return kyg_shouldIndentWhileEditingRowAtIndexPath(tableView, indexPath);
    }
    return YES;
}

// The willBegin/didEnd methods are called whenever the 'editing' property is automatically changed by the table (allowing insert/delete/move). This is done by a swipe activating a single row
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath API_UNAVAILABLE(tvos){
    if (kyg_willBeginEditingRowAtIndexPath) {
        kyg_willBeginEditingRowAtIndexPath(tableView, indexPath);
    }
}
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(nullable NSIndexPath *)indexPath API_UNAVAILABLE(tvos){
    if (kyg_didEndEditingRowAtIndexPath) {
        kyg_didEndEditingRowAtIndexPath(tableView, indexPath);
    }
}

// Moving/reordering

// Allows customization of the target row for a particular row as it is being moved/reordered
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath{
    if (kyg_targetIndexPathForMoveFromRowAtIndexPath) {
        return kyg_targetIndexPathForMoveFromRowAtIndexPath(tableView,sourceIndexPath,proposedDestinationIndexPath);
    }
    //FIXME: 不知道是啥东西，回头得试试先
    return sourceIndexPath;
}

// Indentation  缩进~暂时不知道干啥的
//FIXME: 缩进~暂时不知道干啥的
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath{
    if (kyg_indentationLevelForRowAtIndexPath) {
        return kyg_indentationLevelForRowAtIndexPath(tableView, indexPath);
    }
    return 0;
}

// Copy/Paste.  All three methods must be implemented by the delegate.


// Focus

- (BOOL)tableView:(UITableView *)tableView canFocusRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(9.0)){
    
    if (kyg_canFocusRowAtIndexPath) {
        return kyg_canFocusRowAtIndexPath(tableView, indexPath);
    }
    return YES;
}
- (BOOL)tableView:(UITableView *)tableView shouldUpdateFocusInContext:(UITableViewFocusUpdateContext *)context API_AVAILABLE(ios(9.0)){
    
    if (kyg_shouldUpdateFocusInContext) {
        return kyg_shouldUpdateFocusInContext(tableView, context);
    }
    return true;
}
- (void)tableView:(UITableView *)tableView didUpdateFocusInContext:(UITableViewFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator API_AVAILABLE(ios(9.0)){
    if (kyg_didUpdateFocusInContext) {
        kyg_didUpdateFocusInContext(tableView, context, coordinator);
    }
}
- (nullable NSIndexPath *)indexPathForPreferredFocusedViewInTableView:(UITableView *)tableView API_AVAILABLE(ios(9.0)){
    
    if (kyg_indexPathForPreferredFocusedViewInTableView) {
        return kyg_indexPathForPreferredFocusedViewInTableView(tableView);
    }
    return nil;
}

/// Determines if the row at the specified index path should also become selected when focus moves to it.
/// If the table view's global selectionFollowsFocus is enabled, this method will allow you to override that behavior on a per-index path basis. This method is not called if selectionFollowsFocus is disabled.
- (BOOL)tableView:(UITableView *)tableView selectionFollowsFocusForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(15.0)) API_UNAVAILABLE(watchos, tvos){
    
    if (kyg_selectionFollowsFocusForRowAtIndexPath) {
        return kyg_selectionFollowsFocusForRowAtIndexPath(tableView,indexPath);
    }
    return true;
}

@end
